package com.zegome.game.oanquan.scene.play;

import java.util.ArrayList;
import java.util.Vector;

import android.util.Log;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.zegome.game.action.IAction;
import com.zegome.game.action.interpolation.BackInFunction;
import com.zegome.game.action.percentage.BasePercentageValueGroupAction.IPercentageGroupActionListener;
import com.zegome.game.entity.IEntity;
import com.zegome.game.entity.action.MoveAction;
import com.zegome.game.entity.action.IEntityAction.IEntityActionListener;
import com.zegome.game.entity.action.group.MovePercentageAction;
import com.zegome.game.entity.action.group.PercentageEntityGroupAction;
import com.zegome.game.entity.sprite.AnimatedSprite;
import com.zegome.game.entity.sprite.Sprite;
import com.zegome.game.entity.text.Text;
import com.zegome.game.handler.IUpdateHandler;
import com.zegome.game.handler.TimeTaskUpdate;
import com.zegome.game.handler.TimeTaskUpdate.TimeTaskListener;
import com.zegome.game.oanquan.GameCenter;
import com.zegome.game.oanquan.HighScoreHelper;
import com.zegome.game.oanquan.ImageAssets;
import com.zegome.game.oanquan.SoundAsset;
import com.zegome.game.oanquan.gamelogic.AI;
import com.zegome.game.oanquan.scene.play.CownDownClock.ITask;

/**
 * (C) 2013 ZeroTeam
 * @author QuanLT
 */

public class BoardManager {

	// ===========================================================
	// Constants
	// ===========================================================
	public static final int BOARD_WIDTH = 700;
	public static final int BOARD_HEIGHT = 200;
	
	public static final int TOTAL_POND = 12;
	public static final int NUMBER_PLAYER = 2;
	public static final int TOTAL_STONE = 50;
	
	public static final byte FIRST_PLAYER = 0;
	public static final byte SECOND_PLAYER = 1;

	public static final int LEFT = -1;
	public static final int RIGHT = 1;
	
	public static final float DELTA = 20f;

	private static final float VELOCITY = 300;
	
	// ===========================================================
	// Fields
	// ===========================================================
	private final PlayingScreen mScreen;
	
	private AI mAI;
	private CownDownClock mCownDownClockThinking;
	private CownDownClock mCownDownClockTime;
	
	private final PondData[] mPonds;
	private PondData mDevidePond;
	private final ScorePond[] mScorePonds;
	
	private final Text[] mPondTexts;
	private Text mCountTimeText;

	private Sprite[] mStoneList;
	private Sprite[] mBigStones;
	private Sprite mSelectedSprite;
	private Sprite mAiSprite;
	private Sprite mSuuSprite;
	private Sprite mTiSprite;
	
	private AnimatedSprite mFlagSprite;

	private Sound mWinSound;
	private Sound mLoseSound;
	private Sound mStoneSound;
	private Sound mEatCourtinSound;
	private Sound mEatSound1;
	private Sound mEatSound4;
	private Sound mEatSound8;

	private final Vector2 mPosition;
	private Vector3 mTouchDownPosition;
	private Vector3 mTouchUpPosition;

	private IUpdateHandler mGameUpdate;
	
	private boolean isAcceptTouch = false;
	private boolean isTouchUp = false;
	private boolean isAcceptCheck = false;
	private boolean isNeedAddStone = false;
	private boolean isShowResult = false;
	private boolean isComputerable = false;

	private boolean isComputer = false;
	
	private int mTraceIndex = -1;
	private int mCurrentFlag;
	private int mDirection = 1;
	
	private int mHighScoreIndex;
	private int mScore;
	
	// ===========================================================
	// Constructor
	// ===========================================================
	public BoardManager(final PlayingScreen screen, final int xPos, final int yPos) {
		mScreen = screen;

		mPosition = new Vector2(xPos, yPos);
		mPonds = new PondData[TOTAL_POND];
		mPondTexts = new Text[TOTAL_POND];
		mScorePonds = new ScorePond[NUMBER_PLAYER];
		
//		if (GameCenter.isNeedAI) {
			mAI = new AI(GameCenter.DEPTH);
			mAI.isLogNode = true;

			mCownDownClockThinking = new CownDownClock(3f, false, CownDownClock.GAME_MODE, new ITask() {
				
				@Override
				public void onTask() {
					// TODO Auto-generated method stub
					isComputerable = true;
					mCownDownClockThinking.pause();
				}
			});
//		}
		
		mCownDownClockTime = new CownDownClock(GameCenter.TIME_DEFAULT, true, CownDownClock.GAME_MODE, new ITask() {
			
			@Override
			public void onTask() {
				// TODO Auto-generated method stub
				mCownDownClockTime.pause();
				finishTurnTime();
			}
		});
				
		init();
	}
	
	private void init() {
		mTouchDownPosition = new Vector3();
		mTouchUpPosition = new Vector3();
		
		final TextureAtlas ingameAtlas = mScreen.getController().get(ImageAssets.ASSET_FOLDER_ATLAS + ImageAssets.ATLAS_INGAME, TextureAtlas.class);
		
		final TextureRegion[] bigStoneRegions = new TextureRegion[2];
		bigStoneRegions[0] = ingameAtlas.findRegion(ImageAssets.REGION_BIG_STONE_0);
		bigStoneRegions[1] = ingameAtlas.findRegion(ImageAssets.REGION_BIG_STONE_1);
		final TextureRegion stoneRegion = ingameAtlas.findRegion(ImageAssets.REGION_STONE);
		final TextureRegion aiRegion = ingameAtlas.findRegion(ImageAssets.REGION_AI);
		final TextureRegion tiRegion = ingameAtlas.findRegion(ImageAssets.REGION_TI);
		final TextureRegion suuRegion = ingameAtlas.findRegion(ImageAssets.REGION_SUU);
		final TextureRegion choiceRegion = ingameAtlas.findRegion(ImageAssets.REGION_CHOICE);
		final TextureRegion[] flagRegions = new TextureRegion[3];
		
		for (int i = 0; i < 3; i++) {
			flagRegions[i] = ingameAtlas.findRegion(ImageAssets.REGION_FLAG + String.valueOf(i));
		}
		
		mAiSprite = new Sprite(80, 335, aiRegion);
		mTiSprite = new Sprite(580, 0, tiRegion);
		mSuuSprite = new Sprite(115, 335, suuRegion);
		mScreen.attachChild(mAiSprite);
		mScreen.attachChild(mTiSprite);
		mScreen.attachChild(mSuuSprite);
		mAiSprite.setVisible(false);
		mSuuSprite.setVisible(false);
		
		mSelectedSprite = new Sprite(0, 0, choiceRegion);
		mSelectedSprite.setVisible(false);
		mScreen.attachChild(mSelectedSprite);
		
		mFlagSprite = new AnimatedSprite(0.15f, 0, 0, flagRegions);
		mScreen.attachChild(mFlagSprite);
		
		for (int i = 0; i < TOTAL_POND; i++) {
			mPonds[i] = new PondData(i / 6, i, i % 6 == 0);
		}

		final BitmapFont font = mScreen.getController().get(GameCenter.ASSET_FOLDER_FONT + GameCenter.ASSET_FONT, BitmapFont.class);
		
		mCountTimeText = new Text(170, 40, "", font);
		mScreen.attachChild(mCountTimeText);
		
		for (int i = 0; i < TOTAL_POND; i++) {
			mPondTexts[i] = new Text(mPonds[i].mPosition.x + 5, mPonds[i].mPosition.y + 35, "", font);
			mPonds[i].setText(mPondTexts[i]);
			mPonds[i].resetText();
			
			mPondTexts[i].setZIndex(1);
			if (i == 0) {
				mPondTexts[i].setPosition(130, 340);
			} else if (i == 6) {
				mPondTexts[i].setPosition(660, 185);
			}
			mScreen.attachChild(mPondTexts[i]);
		}

		final Text[] texts = new Text[GameCenter.NUMBER_PLAYER];
		mScorePonds[0] = new ScorePond(455, 10, 0);
		mScorePonds[1] = new ScorePond(225, 350, 1);
		
		mBigStones = new Sprite[NUMBER_PLAYER];
		for (int i = 0; i < GameCenter.NUMBER_PLAYER; i++) {
			mBigStones[i] = new Sprite(0, 0, bigStoneRegions[i]);
			texts[i] = new Text(370, 85 + i * 320, ""+0, font);
			mScorePonds[i].setText(texts[i]);
			texts[i].setZIndex(1);
			
			mScreen.attachChild(mBigStones[i]);
			mScreen.attachChild(texts[i]);
		}
		
		mBigStones[0].setPosition(115, 150);
		mBigStones[1].setPosition(650, 255);
		
		mStoneList = new Sprite[TOTAL_STONE];
		for (int i = 0; i < TOTAL_STONE; i++) {
			mStoneList[i] = new Sprite(0, 0,stoneRegion);
			mScreen.attachChild(mStoneList[i]);
		}

		getSound();
		
		mGameUpdate = new IUpdateHandler() {
			
			@Override
			public void reset() {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onUpdate(float delta) {
				// TODO Auto-generated method stub
				if (!GameCenter.isNeedAI) {
					mCountTimeText.setText(String.valueOf((int)Math.ceil(mCownDownClockTime.getCurrentCownDownTime())));
					updateBoard();
				} else {
					updateBoardAI();
				}
			}
			
			@Override
			public boolean isDetachSelf() {
				// TODO Auto-generated method stub
				return false;
			}
		};
		
		mScreen.setNeedSort(true);
	}
	
	// ===========================================================
	// Getter & Setter
	// ===========================================================
	private void getSound() {
		mWinSound = mScreen.getController().get(SoundAsset.ASSET_SOUND_FOLDER + SoundAsset.ASSET_SOUND_WIN, Sound.class);
		mLoseSound = mScreen.getController().get(SoundAsset.ASSET_SOUND_FOLDER + SoundAsset.ASSET_SOUND_LOSE, Sound.class);
		mStoneSound = mScreen.getController().get(SoundAsset.ASSET_SOUND_FOLDER + SoundAsset.ASSET_SOUND_STONE, Sound.class);
		mEatCourtinSound = mScreen.getController().get(SoundAsset.ASSET_SOUND_FOLDER + SoundAsset.ASSET_SOUND_EAT_COURTING, Sound.class);
		mEatSound1 = mScreen.getController().get(SoundAsset.ASSET_SOUND_FOLDER + SoundAsset.ASSET_SOUND_EAT_1, Sound.class);
		mEatSound4 = mScreen.getController().get(SoundAsset.ASSET_SOUND_FOLDER + SoundAsset.ASSET_SOUND_EAT_4, Sound.class);
		mEatSound8 = mScreen.getController().get(SoundAsset.ASSET_SOUND_FOLDER + SoundAsset.ASSET_SOUND_EAT_8, Sound.class);
	}
	
	public int getScore() {
		return mScore;
	}
	
	public int getHighScoreIndex() {
		return mHighScoreIndex;
	}
	
	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	// ===========================================================
	// Methods
	// ===========================================================
	
	public void updateBoard() {
		if (mScreen.mState == PlayingScreen.PAUSE || mScreen.mState == PlayingScreen.RESULT) {
			return;
		}
		
		if (isAcceptTouch) {
			touchProcessor();
		}

		if (isNeedAddStone) {
			isNeedAddStone = false;
			
			if(!addStoneScoreToPond(mPonds)) {
				resultGame(false, mCurrentFlag == FIRST_PLAYER ? SECOND_PLAYER : FIRST_PLAYER);
//				endGame();
			}
		}
	}

	public void updateBoardAI() {
		if (mScreen.mState == PlayingScreen.PAUSE || mScreen.mState == PlayingScreen.RESULT) {
			return;
		}
		
		if (mCurrentFlag == FIRST_PLAYER) {
			mCountTimeText.setText(String.valueOf((int)Math.ceil(mCownDownClockTime.getCurrentCownDownTime())));
		}
		
		if (isAcceptTouch) {
			if (isShowResult) {
				if (Gdx.input.justTouched()) {
					isShowResult = false;
					endGame();
				}
				return;
			}
			
			if (mCurrentFlag == FIRST_PLAYER) {
				if (Gdx.input.justTouched()) {
					isTouchUp = false;
					configPosition(mTouchDownPosition, Gdx.input.getX(),
							Gdx.input.getY());
					if (contains(mTouchDownPosition.x, mTouchDownPosition.y,
							mCurrentFlag)) {

						final int x = (int) (mTouchDownPosition.x - mPosition.x)
								/ PondData.WIDTH;
						final int y = (int) (mTouchDownPosition.y - mPosition.y)
								/ PondData.HEIGHT;
						final int index = (y== 0 ? x : (TOTAL_POND - x));
						
						if (mPonds[index].getStone() > 0) {
							isAcceptCheck = true;
							mSelectedSprite.setVisible(true);

							mDevidePond = mPonds[index];

							mSelectedSprite.setPosition(mDevidePond.mPosition.x - 32,
									mDevidePond.mPosition.y);
						}
					}
				} else if (Gdx.input.isTouched()) {
					configPosition(mTouchUpPosition, Gdx.input.getX(), Gdx.input.getY());
				} else if (isAcceptCheck) {
					if (!isTouchUp) {
						isTouchUp = true;
						isAcceptCheck = false;
						final float deltaX = mCurrentFlag == FIRST_PLAYER ? mTouchUpPosition.x - mTouchDownPosition.x 
								: mTouchDownPosition.x - mTouchUpPosition.x;
						
						mDirection = deltaX > 0 ? RIGHT : LEFT;
							
						if (deltaX * mDirection > DELTA) {
							isAcceptTouch = false;
							mCownDownClockTime.pause();
							startDevidePond(mDirection);
							mScorePonds[0].addTimeSurPlus((int)(Math.ceil(mCownDownClockTime.getCurrentCownDownTime())));
						}
					}
				}
			} else {
				if (isComputer) {
					isComputer = false;
					mCownDownClockThinking.reset();
					mScreen.registerUpdateHandler(mCownDownClockThinking);
					mScreen.postRunnable(new Runnable() {
					
						@Override
						public void run() {
							mAI.start(mPonds, mScorePonds[0].getScore(), mScorePonds[1].getScore());
						}
					});
				} else if (mAI.isComplete && isComputerable) {
					mScreen.postRunnable(new Runnable() {
						
						@Override
						public void run() {
							if (Gdx.graphics.getDeltaTime() < 0.1f) {
								mAI.isComplete = false;
								isComputerable = false;
								
								mDirection = mAI.mAction.mDirection;
								mDevidePond = mPonds[mAI.mAction.mIndex];
								
								startDevidePond(mDirection);
								mScorePonds[1].addTimeSurPlus((int)(GameCenter.TIME_DEFAULT - mCownDownClockThinking.getCurrentCownDownTime()));
							}
						}
					});
				}
			}
		}
		
		if (!isShowResult && isNeedAddStone) {
			isNeedAddStone = false;
			
			if(!addStoneScoreToPond(mPonds)) {
				resultGame(false, mCurrentFlag == FIRST_PLAYER ? SECOND_PLAYER : FIRST_PLAYER);
//				endGame();
			}
		}
	}
	
	private void touchProcessor() {
		if (isShowResult) {
			if (Gdx.input.justTouched()) {
				isShowResult = false;
				endGame();
			}
			return;
		}
		
		if (Gdx.input.justTouched()) {
			isTouchUp = false;
			configPosition(mTouchDownPosition, Gdx.input.getX(),
					Gdx.input.getY());
			if (contains(mTouchDownPosition.x, mTouchDownPosition.y,
					mCurrentFlag)) {

				final int x = (int) (mTouchDownPosition.x - mPosition.x)
						/ PondData.WIDTH;
				final int y = (int) (mTouchDownPosition.y - mPosition.y)
						/ PondData.HEIGHT;
				final int index = (y== 0 ? x : (TOTAL_POND - x));
				
				if (mPonds[index].getStone() > 0) {
					isAcceptCheck = true;
					mSelectedSprite.setVisible(true);

					mDevidePond = mPonds[index];

					mSelectedSprite.setPosition(mDevidePond.mPosition.x - 32,
							mDevidePond.mPosition.y);
				}
				
			}
		} else if (Gdx.input.isTouched()) {
			configPosition(mTouchUpPosition, Gdx.input.getX(), Gdx.input.getY());
		} else if (isAcceptCheck) {
			if (!isTouchUp) {
				isTouchUp = true;
				isAcceptCheck = false;
				final float deltaX = mCurrentFlag == 0 ? mTouchUpPosition.x - mTouchDownPosition.x 
						: mTouchDownPosition.x - mTouchUpPosition.x;
				
				mDirection = deltaX > 0 ? RIGHT : LEFT;
					
				if (deltaX * mDirection > DELTA) {
					mCownDownClockTime.pause();
					isAcceptTouch = false;
					startDevidePond(mDirection);
					mScorePonds[mCurrentFlag].addTimeSurPlus((int)(Math.ceil(mCownDownClockTime.getCurrentCownDownTime())));
				}
			}
		}
	}

	void configPosition(final Vector3 vector, final float x, final float y) {
		vector.set(x, y, 0);
		mScreen.getCamera().unproject(vector);
	}

	boolean contains(final float x, final float y, final int flag) {
		if (flag == 1 && GameCenter.isNeedAI) return false;
		if (mPosition.x + PondData.WIDTH < x
				&& mPosition.x + BOARD_WIDTH - PondData.WIDTH > x
				&& mPosition.y + flag * PondData.HEIGHT < y
				&& mPosition.y + (flag + 1) * PondData.HEIGHT > y)
			return true;
		return false;
	}

	public void startGame() {
		setFlag(FIRST_PLAYER);
		startUpFlag();
		buildBoard();
		
		mScore = 0;
		mHighScoreIndex = -1;
		
		if (GameCenter.isNeedAI) {
			mAiSprite.setVisible(true);
			mSuuSprite.setVisible(false);
		} else {
			mAiSprite.setVisible(false);
			mSuuSprite.setVisible(true);
		}
		
		mScreen.registerUpdateHandler(mGameUpdate);
		mScreen.registerUpdateHandler(mCownDownClockTime);
		mCownDownClockTime.setTimeTask(GameCenter.TIME_DEFAULT);
		mCownDownClockTime.reStart();
	}

	private void resultGame(final boolean isNormal, final byte winner) {
		isShowResult = true;
		isAcceptTouch = false;
		mScreen.mState = PlayingScreen.RESULT;
		
		mCownDownClockTime.pause();
		
		if (isNormal) { 
			final TimeTaskUpdate timeTask = new TimeTaskUpdate() {
				
				@Override
				public void task(float delta) {
					
				}

				@Override
				public boolean isDetachSelf() {
					// TODO Auto-generated method stub
					return false;
				}
			};
			timeTask.addFinishTaskListener(new TimeTaskListener() {
				
				@Override
				public void onFinishTask(float delta) {
					mScreen.postRunnable(new Runnable() {
						
						@Override
						public void run() {
							mScreen.unregisterUpdateHandler(timeTask);
							showResult(winner);
						}
					});
				}
			});
			timeTask.start(3);
			mScreen.registerUpdateHandler(timeTask);
		} else {
			showResult(winner);
		}
	}
	
	private void endGame() {
		resetFlag();
		hideBoard();
	}

	private boolean addStoneScoreToPond(final PondData[] ponds) {
		if (mScorePonds[mCurrentFlag].getScore() < 5) {
			return false;
		}
		
		final int currentFlag = mCurrentFlag;
		if (currentFlag == 0) {
			for (int i = 1; i <= 5; i++) {
				final PondData pond = ponds[i];
				final Sprite sprite = mScorePonds[currentFlag].removeStone();
				final Vector2 pos = pond.createPosition();
				final float x = pos.x - sprite.getX();
				final float y = pos.y - sprite.getY();
				
				final MoveAction modifier = new MoveAction(0.75f,
						sprite.getX(), sprite.getX() + x, sprite.getY(),
						sprite.getY() + y);
				final IEntityActionListener listener = new IEntityActionListener() {
					
					@Override
					public void onActionStarted(IAction<IEntity> pAction, IEntity pItem) {
						pItem.setZIndex(1);
					}
					
					@Override
					public void onActionFinished(IAction<IEntity> pAction, IEntity pItem) {
						pItem.setZIndex(0);
						pond.attachStone(sprite);
						if (pond.getIndex() == 5) {
							isAcceptTouch = true;
						}
					}
				};
				
				modifier.addActionListener(listener);
				sprite.registerAction(modifier);
			}
		} else {
			for (int i = 7; i <= 11; i++) {
				final Sprite sprite = mScorePonds[currentFlag].removeStone();
				final PondData pond = ponds[i];
				final Vector2 pos = pond.createPosition();
				final float x = pos.x - sprite.getX();
				final float y = pos.y - sprite.getY();
				
				final MoveAction modifier = new MoveAction(0.75f,
						sprite.getX(), sprite.getX() + x, sprite.getY(),
						sprite.getY() + y);
				final IEntityActionListener listener = new IEntityActionListener() {
					
					@Override
					public void onActionStarted(IAction<IEntity> pAction, IEntity pItem) {
						pItem.setZIndex(1);
					}
					
					@Override
					public void onActionFinished(IAction<IEntity> pAction, IEntity pItem) {
						pItem.setZIndex(0);
						pond.attachStone(sprite);
						if (pond.getIndex() == 11) {
							isAcceptTouch = true;
						}
					}
				};
				
				modifier.addActionListener(listener);
				sprite.registerAction(modifier);
			}
		}
		return true;
	}
	
	private void finishTurnTime() {

		Log.e("finishTurnTime", "finishTurnTime");
		
		isAcceptTouch = false;
		final int factor = (mCurrentFlag == FIRST_PLAYER ? 1 : 7);
		
		final Vector<Integer> index = new Vector<Integer>();
		for (int i = 0; i < 5; i++) {
			if (mPonds[i + factor].getStone() > 0) {
				final int k = i + factor;
				index.add(k);
			}
		}
		
		if (index.isEmpty())
			throw new IllegalArgumentException("loi finishTurnTime");
		
		mTraceIndex = index.get(GameCenter.GAME_RANDOM.nextInt(index.size()));
		mDirection = (GameCenter.GAME_RANDOM.nextInt(2) == 0 ? BoardManager.LEFT : BoardManager.RIGHT);
		mDevidePond = mPonds[mTraceIndex];
		startDevidePond(mDirection);
		return;
	}
	
	public void startDevidePond(final int direction) {
		mDirection = direction;
		mTraceIndex = mDevidePond.getIndex();
		
		mSelectedSprite.setVisible(false);
		mDevidePond.startDevide();
		devidePond();
		mDevidePond.finishDevide();
	}

	private void devidePond() {
		final int count = mDevidePond.mStoneDevide;
		if (count > 0) {
			final Sprite stone = mDevidePond.removeStone();
			final Vector2 position = new Vector2(stone.getX(), stone.getY());
			mDevidePond.mStoneDevide--;
			mTraceIndex += mDirection;
			if (mTraceIndex > TOTAL_POND - 1) {
				mTraceIndex = 0;
			} else if (mTraceIndex < 0) {
				mTraceIndex = TOTAL_POND - 1;
			}
			final int index = mTraceIndex;
			mPonds[index].addPosition(stone);
			final float a = stone.getX() - position.x;
			final float b = stone.getY() - position.y;
			final float time = (float) Math.sqrt(a * a + b * b) / VELOCITY;
			final MoveAction modifier = new MoveAction(time, position.x,
					stone.getX(), position.y, stone.getY(), BackInFunction.getInstance());
			
			final IEntityActionListener listener = new IEntityActionListener() {

				@Override
				public void onActionStarted(IAction<IEntity> pAction,
						IEntity item) {
					item.setZIndex(1);
				}

				@Override
				public void onActionFinished(IAction<IEntity> pAction,
						IEntity item) {
					if (GameCenter.isSound) mStoneSound.play();
					
					mPonds[index].attachStone(stone);
					item.setZIndex(0);
					devidePond();
				}
			};

			modifier.addActionListener(listener);
			
			stone.setPosition(position.x, position.y);
			stone.registerAction(modifier);
		} else {
			int index = mTraceIndex;
			index = nextIndex(index, mDirection);
			if (mPonds[index].isCourting()) {
				nextTurn();
				
			} else if (mPonds[index].getStone() == 0) {
				index = nextIndex(index, mDirection);
				checkEatPond(mPonds, index, mDirection);
			} else if (mPonds[index].getStone() != 0) {
				mDevidePond = mPonds[index];
				startDevidePond(mDirection);
			} else {
				nextTurn();
			}
		}
	}

	private void checkEatPond(final PondData[] ponds, final int index, final int direction) {
		final ArrayList<Integer> eating = new ArrayList<Integer>();
		
		boolean isContinue = true;
		boolean isStart = false;
		int checkIndex = index;
		while(isContinue) {
			if (ponds[checkIndex].getStone() != 0 && ponds[checkIndex].isEating()) {
				if (checkIndex == index && isStart) break;
				eating.add(checkIndex);

				checkIndex = nextIndex(checkIndex, direction);
				if (ponds[checkIndex].getStone() == 0) {
					checkIndex = nextIndex(checkIndex, direction);
				} else {
					isContinue = false;
				}
			} else {
				isContinue = false;
			}
			if (!isStart) {
				isStart = true;
			}
		}		
		
		final int count = eating.size();
		
		if (count > 0) {
			
			if (count >= 8) {
				mEatSound8.play();
			} else if (count >= 4) {
				mEatSound4.play();
			} else {
				mEatSound1.play();
			}
			
			final PercentageEntityGroupAction groupAction = new PercentageEntityGroupAction(0.75f);
			
			for (int k = count - 1; k >= 0; k--) {
				final int e = eating.get(k);
				final int size = ponds[e].getStone();
				final int currentFlag = mCurrentFlag;
				float x = mScorePonds[currentFlag].mPosition.x - ponds[e].mPosition.x + 20;
				float y = mScorePonds[currentFlag].mPosition.y - ponds[e].mPosition.y - 15;
				if (ponds[e].isCourting() && e == 0) {
					x -= 10;
					y -= 60;
				} else if (ponds[e].isCourting() && e == 6) {
					x += 20;
					y += 50;
				} else {
					x += 10;
	//				y -= 15;
				}
				
				for (int i = 0; i < size; i++) {
					final Sprite sprite = ponds[e].removeStone();
					
					MovePercentageAction percentageAction = new MovePercentageAction(sprite, sprite.getX(), sprite.getX() + x, sprite.getY(),
							sprite.getY() + y);
					
					groupAction.add(percentageAction);
					
					mScorePonds[currentFlag].attachStone(sprite);

					if (ponds[e].isCourting()) {
						mScorePonds[currentFlag].eatCourting();
						ponds[e].setEated(true);
						if (GameCenter.isSound)
							mEatCourtinSound.play();
					}
				}
				
			}
			
			IPercentageGroupActionListener listener = new IPercentageGroupActionListener() {

				@Override
				public void onActionStarted() {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onActionFinished() {
					checkEndGame(ponds);
					nextTurn();
				}
			};
			groupAction.addActionListener(listener);
			groupAction.setAutoUnregisterWhenFinished(true);
			mScreen.registerUpdateHandler(groupAction);
		} else {
			nextTurn();
		}
	}

	private void checkEndGame(final PondData[] ponds) {
		if (ponds[0].getStone() == 0 && ponds[0].isEated() 
				&& ponds[6].getStone() == 0 && ponds[6].isEated()) {
			byte winner = PlayingScreen.SECOND_PLAYER;
							
			for (int k = 1; k <= 5; k++) {
				final int size = ponds[k].getStone();
				final float x = mScorePonds[FIRST_PLAYER].mPosition.x - ponds[k].mPosition.x;
				final float y = mScorePonds[FIRST_PLAYER].mPosition.y - ponds[k].mPosition.y;
				if (mPonds[k].getStone() > 0) {
					for (int n = 0; n < size; n++) {
						final Sprite sprite = ponds[k].removeStone();
						final MoveAction modifier = new MoveAction(0.75f,
								sprite.getX(), sprite.getX() + x, sprite.getY(),
								sprite.getY() + y);
						final IEntityActionListener listener = new IEntityActionListener() {
							
							@Override
							public void onActionStarted(IAction<IEntity> pAction, IEntity pItem) {
								pItem.setZIndex(1);
							}
							
							@Override
							public void onActionFinished(IAction<IEntity> pAction, IEntity pItem) {
								pItem.setZIndex(0);
							}
						};
						
						modifier.addActionListener(listener);
						sprite.registerAction(modifier);
						mScorePonds[FIRST_PLAYER].attachStone(sprite);
					}
				}
			}
			
			for (int k = 7; k <= 11; k++) {
				final int size = ponds[k].getStone();
				final float x = mScorePonds[SECOND_PLAYER].mPosition.x - ponds[k].mPosition.x;
				final float y = mScorePonds[SECOND_PLAYER].mPosition.y - ponds[k].mPosition.y;
				if (mPonds[k].getStone() > 0) {
					for (int n = 0; n < size; n++) {
						final Sprite sprite = ponds[k].removeStone();
						final MoveAction modifier = new MoveAction(0.75f,
								sprite.getX(), sprite.getX() + x, sprite.getY(),
								sprite.getY() + y);
						final IEntityActionListener listener = new IEntityActionListener() {
							
							@Override
							public void onActionStarted(IAction<IEntity> pAction, IEntity pItem) {
								pItem.setZIndex(1);
							}
							
							@Override
							public void onActionFinished(IAction<IEntity> pAction, IEntity pItem) {
								pItem.setZIndex(0);
							}
						};
						
						modifier.addActionListener(listener);
						sprite.registerAction(modifier);
						mScorePonds[SECOND_PLAYER].attachStone(sprite);
					}
				}
			}
			
			final int s1 = mScorePonds[FIRST_PLAYER].getScore(GameCenter.LEVEL);
			final int s2 = mScorePonds[SECOND_PLAYER].getScore(GameCenter.LEVEL);
			
			if (s1 > s2) {
				winner = PlayingScreen.FIRST_PLAYER;
			} else if (s1 == s2) {
				winner = PlayingScreen.DRAW;
			}
			resultGame(true, winner);
		}
	}
	
	private void nextTurn() {
		if (isShowResult)
			return;
		
		isAcceptTouch = true;
		mTraceIndex = -1;
		setFlag(mCurrentFlag == FIRST_PLAYER ? SECOND_PLAYER : FIRST_PLAYER);
		
		if (!isComputer && mCurrentFlag == 1 && GameCenter.isNeedAI ) {
			isComputer = true;
		}
		
		if (isShowResult) {
			isAcceptTouch = false;
			return;
		}
		
		if (mCurrentFlag == 0) {
			isNeedAddStone = true;
			isAcceptTouch = false;
			for (int i = 1; i <= 5; i++) {
				if (mPonds[i].getStone() != 0) {
					isNeedAddStone = false;
					isAcceptTouch = true;
					break;
				}
			}
		} else {
			isNeedAddStone = true;
			isAcceptTouch = false;
			for (int i = 7; i <= 11; i++) {
				if (mPonds[i].getStone() != 0) {
					isNeedAddStone = false;
					isAcceptTouch = true;
					break;
				}
			}
		}
	}

	private int nextIndex(int index, final int direction) {
		index += direction;
		return index = checkIndex(index);
	}

	private int checkIndex(int index) {
		if (index >= TOTAL_POND) {
			index -= TOTAL_POND;
		} else if (index < 0) {
			index += TOTAL_POND;
		}
		return index;
	}

	private void buildBoard() {
		if (mAI != null) {
			mAI.setDepth(GameCenter.DEPTH);
		}
		
		for (int i = 0; i < TOTAL_POND; i++) {
			mPonds[i].clear();
			mPonds[i].reset();
		}

		int count = 0;
		int index = 0;
		while (count < TOTAL_POND - 1) {
			count++;
			if (count == 6) {
				continue;
			}
			
			for (int i = 0; i < 5; i++) {
				mPonds[count].attachStone(mStoneList[index]);
				mPonds[count].addPosition(mStoneList[index]);
				index++;
			}
		}
		mSelectedSprite.setVisible(false);
		
		for (int i = 0; i < GameCenter.NUMBER_PLAYER; i++) {
			mScorePonds[i].mText.setVisible(true);
			mScorePonds[i].clear();
		}
		
		for (int i = 0; i < TOTAL_STONE; i++) {
			mStoneList[i].setVisible(true);
		}
		
		mFlagSprite.setVisible(true);
		
		for (int i = 0; i < TOTAL_POND; i++) {
			mPonds[i].setText(mPondTexts[i]);
			mPonds[i].resetText();
			mPondTexts[i].setVisible(true);
		}
	}

	private void hideBoard() {
//		mBoardSprite.setVisible(false);
		mSelectedSprite.setVisible(false);
		
		for (int i = 0; i < GameCenter.NUMBER_PLAYER; i++) {
//			mScoreFrames[i].setVisible(false);
			mScorePonds[i].mText.setVisible(false);
		}
		
		for (int i = 0; i < TOTAL_STONE; i++) {
			mStoneList[i].setVisible(false);
		}
		
		mFlagSprite.setVisible(false);
		
		for (int i = 0; i < TOTAL_POND; i++) {
			mPondTexts[i].setVisible(false);
		}
	}
	
	private void showResult(final byte winner) {
		if (GameCenter.isNeedAI) {
			mScore = mScorePonds[PlayingScreen.FIRST_PLAYER].getScore(GameCenter.LEVEL);
			final int index = HighScoreHelper.hasHighScore(mScreen.getController().getActivity(), mScore);
			if (index > -1) {
				mHighScoreIndex = index;
			}
		}
		
		if (winner == PlayingScreen.FIRST_PLAYER) {
			if (GameCenter.isSound)
				mWinSound.play();
		} else if (winner == PlayingScreen.SECOND_PLAYER){
			if (GameCenter.isSound)
				mLoseSound.play();
		} else {
			
		}
		mScreen.showResult(winner, mScorePonds[0].getScore(GameCenter.LEVEL), mScorePonds[1].getScore(GameCenter.LEVEL));
	}
	
	public void clearAction() {
		mScreen.clearUpdateHandler();
		for (int i = 0; i < TOTAL_STONE; i++) {
			mStoneList[i].clearAction();
			mStoneList[i].clearUpdateHandler();
		}
	}
	
	public void setFlag(final int flag) {
		mCurrentFlag = flag;
		if (GameCenter.isNeedAI) {
			if (mCurrentFlag == FIRST_PLAYER) {
				mCownDownClockTime.reStart();
			}
		} else {
			mCownDownClockTime.reStart();
		}
		
		mFlagSprite.setPosition(mScorePonds[mCurrentFlag].mText.getX() - 60, mScorePonds[mCurrentFlag].mText.getY());
	}

	private void startUpFlag() {
		isAcceptTouch = true;
		isTouchUp = false;
		isAcceptCheck = false;
		isShowResult = false;
		mScreen.mState = PlayingScreen.PLAYING;
		
	}

	private void resetFlag() {
		isAcceptCheck = false;
		isAcceptTouch = false;
		isTouchUp = false;
		isShowResult = false;
	}
	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}
